<!-- 文章分类卡片,显示存在文章的分类，文章数量，点击分类可展开查看分类下的文章 -->
<template>
  <div class="category-list" v-if="filteredCategories.length > 0">
    <h5 class="category-title-icon">
      <i class="fa fa-folder-open"></i> 文章分类
    </h5>
    <div class="underline"></div>
    <ul>
      <li
        v-for="category in filteredCategories"
        :key="category.id"
        class="category-item"
      >
        <span
          @click="toggle(category.id)"
          class="category-name"
          role="button"
          aria-expanded="isOpen(category.id)"
          :aria-controls="'category-' + category.id"
        >
          <span class="category-title">
            <i
              class="fa"
              :class="isOpen(category.id) ? 'fa-angle-down' : 'fa-angle-right'"
            ></i>
            {{ category.name }}
          </span>
          <span class="category-count">
            {{ category.article_count > 99 ? "99+" : category.article_count }}
          </span>
        </span>

        <!-- 分类文章 -->
        <transition name="slide">
          <ul
            v-if="isOpen(category.id)"
            :id="'category-' + category.id"
            class="subcategory-list"
          >
            <li
              v-for="article in category.articles"
              :key="article.id"
              class="subcategory-item"
            >
              <router-link
                :to="{ name: 'article-detail', params: { id: article.id } }"
                >{{ article.title }}</router-link
              >
            </li>
          </ul>
        </transition>
      </li>
    </ul>
  </div>
</template>


<script setup>

const categories = ref([]);
const openCategoryId = ref(null);

const fetchCategories = async () => {
  try {
    const response = await axios.get('/api/cms/categories/get_category_article_info/');
    categories.value = response.data;
  } catch (error) {
    console.error('获取分类失败:', error);
  }
};

const toggle = (categoryId) => {
  openCategoryId.value = openCategoryId.value === categoryId ? null : categoryId;
};

const isOpen = (categoryId) => {
  return openCategoryId.value === categoryId;
};

const filteredCategories = computed(() => {
  return categories.value.filter((category) => category.article_count > 0);
});

onMounted(() => {
  fetchCategories();
});
</script>



<style scoped>
.category-list {
  background-color: var(--card-bg-color, #fff);
  padding: 20px;
  margin-bottom: 20px;
  border-radius: 12px;
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
  transition: background-color 0.3s;
}


.category-title-icon {
  font-size: 1.2em;
  font-weight: bold;
  color: var(--card-title-color, #333);
}

.category-item {
  list-style-type: none;
  margin: 8px 0;
  padding: 5px 0;
  transition: background-color 0.3s;
  border-bottom: 1px dashed #5fb878;
}
.category-name {
  cursor: pointer;
  display: flex;
  justify-content: space-between;
  user-select: none;
}
.category-title {
  font-size: 14px;
  color: var(--card-title-color, #333);
}
.category-title i {
  margin-right: 8px;
}
.category-count {
  color: #fff;
  background-color: #5fb878;
  border-radius: 6px;
  padding: 0.4em 0.8em;
  font-size: 10px;
}
.subcategory-list {
  padding-left: 15px;
}

.subcategory-item {
  list-style: none;
  margin: 5px 0;
  padding: 5px 0;
  color: #5fb878;
  border-bottom: 1px dashed #5fb878;
}
.subcategory-item:last-child {
  border-bottom: none;
  padding-bottom: 0;
}

.subcategory-item a {
  color: inherit;
  font-size: 12px;
  text-decoration: none;
}
.subcategory-item a:hover {
  color: #00bfae;
}

/* 添加过渡动画 */
.slide-enter-active,
.slide-leave-active {
  transition: all 0.3s ease;
}
.slide-enter-from,
.slide-leave-to {
  transform: translateY(-10px);
  opacity: 0;
}
</style>

